function core(defaultOption, resolve, reject) {
  // 解构赋值获取对象里的数据
  let { data, url, method, async, headers, success, error, responseType } =
    defaultOption;

  // 创建ajax
  let xhr;
  if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
  } else {
    xhr = new ActiveXObject("microsoft.XMLHTTP");
  }

  // 根据不同情况转换成各类格式的data参数
  let params = "";

  // data数据转换
  if (JSON.stringify(data) !== "{}") {
    for (k in data) {
      params += k + "=" + data[k] + "&";
    }
    params = params.substr(0, params.length - 1);
  }

  // 建立请求
  xhr.open(
    method,
    url + (!!params && method === "get" ? "?" + params : ""),
    async
  );

  // header判断
  if (typeof headers === "object") {
    if (JSON.stringify(headers) === "{}") {
      error("请求头传递的是一个空对象", xhr);
    }
  } else {
    if (async) reject("headers expected object but got a " + typeof headers);
    throw new Error("headers expected object but got a " + typeof headers);
  }

  // post /json 传参时的方式
  for (h in headers) {
    if (
      h.toLowerCase() == "content-type" &&
      method === "post" &&
      JSON.stringify(data) !== "{}"
    ) {
      if (headers[h].toLowerCase() === "application/json") {
        params = JSON.stringify(data);
      }
    }
    // 设置请求头
    xhr.setRequestHeader(h, headers[h]);
  }

  // 发送请求
  xhr.send(method !== "post" ? null : params);

  // 如果是同步,这里就直接返回结果
  if (!async) {
    return responseType === "json"
      ? JSON.parse(xhr.responseText)
      : xhr.responseText;
  }

  // 响应
  xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
      if (xhr.status >= 200 && xhr.status < 300) {
        let res = xhr.responseText;
        switch (responseType.toLowerCase()) {
          case "text":
            success(res);
            resolve(res);
            break;
          case "json":
            success(JSON.parse(res));
            resolve(JSON.parse(res));
            break;
          default:
            success(res);
            resolve(res);
        }
      }
    }
  };

  xhr.onerror = function (e) {
    error(e, xhr);
    reject(e, xhr);
  };
}

function ajax(options) {
  // 判断是否传入的是一个对象
  let isObject = Object.prototype.toString
    .call(options)
    .replace(/[\[\]]/g, "")
    .substr(7)
    .toLowerCase();

  if (isObject !== "object") {
    throw new Error(
      "传入的必须是一个对象, the param expected a object,but got a " + isObject
    );
  }

  // 设置默认参数
  let defaultOption = {
    url: "",
    method: "get",
    responseType: "json",
    data: {},
    async: true,
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
    },
    success: function (res) {},
    error: function (e) {},
  };

  // 传入对象和默认对象混合
  for (k in options) {
    defaultOption[k] = options[k];
  }

  // 同步异步判断
  if (defaultOption.async === false) {
    return core(defaultOption);
  } else {
    return new Promise((resolve, reject) => {
      core(defaultOption, resolve, reject);
    });
  }
}
